#!/usr/bin/env python
# -*- coding: utf-8; -*-
'''ervo2babilon.py: Produkti dosieron en Babilon formato por konverti al StarDict

La programo legas cxiujn txt-dosierojn el fonta dosierujo kaj kreas dosieron
tauxgan por konverti gxin per stardict-editor.

La formato de la celdosiero:

vorto|sinonimo1|sinonimo2...
priskribo de la vorto

Artikoloj estas apartigitaj per blanka linio. La priskribo povas havi xdxf
markadon (<k>, <kref>, <i>, <b>, <abr>, <br> ktp)

Uzado:
  [python] parseervo.py FONTA-DOSIERUJO CELDOSIERO
  
'''

import sys
import os.path
from glob import glob
import re

def msg(s):
    sys.stderr.write('**** %s\n' % s.encode('utf-8'))

def err(s):
    sys.stderr.write('**** ERARO OKAZIS: %s\n' % s.encode('utf-8'))
    sys.exit(1)

def cxapeligu(s):
    cx2eo = {
        u'cx': u'ĉ', u'Cx': u'Ĉ', u'gx': u'ĝ', u'Gx': u'Ĝ',
        u'hx': u'ĥ', u'Hx': u'Ĥ', u'jx': u'ĵ', u'Jx': u'Ĵ',
        u'sx': u'ŝ', u'Sx': u'Ŝ', u'ux': u'ŭ', u'Ux': u'Ŭ'
        }
    for c in cx2eo:
        s = s.replace(c, cx2eo[c])
    return s

def convertText(txt):
    '''Redoni tekston en xdxf markado
    '''
    TAGS = (
        (u'@', u'◊'),
        (u'\t', u' '),
        (u'<<', u'«'),
        (u'>>', u'»'),
        (u'--', u'―'),
#         (u'\\|', u'▪'),
#         (u'\\|', u'||'),
        (u'\\|', u'‖'),
        (u'/', u'·'),
        (u'`(.)', u'\\1́'),
        (u'<([^>]+)>', u'<kref>\\1</kref>'),
        (u'\\[([^]]+)\\]', u'<k>\\1</k>'),
        (u'_([^_]+)_', u'<i>\\1</i>'),
        (u'{([^}]+)}', u'<abr>\\1</abr>'),
        )
    for p, s in TAGS:
        txt = re.sub(p, s, txt)
    return txt

def writeutf(f, s):
    '''Konservi tekston en la dosieron en utf-8
    '''
    f.write(s.encode('utf-8'))

def writeNest(kwords, text, ftxt):
    '''Konservi artikolon (neston)
    '''
    template = u'%s\n%s\n\n'
    kword = kwords[0]
    kwords = kwords[1:]
    #### metu la artikolon mem kun cxefa kapvorto
    writeutf(ftxt, template % (kword, convertText(text.strip())))
    #### metu cxiujn aliajn kapvortojn kiel ligiloj al la cxefa
    for wrd in kwords:
        txt = u'[%s] _см._ <%s>' % (wrd, kword)
        writeutf(ftxt, template % (wrd, convertText(txt)))

def processNest(raw, ftxt):
    '''Perlabori neston kaj konservi gxin en necesa formato
    raw estas listo de linioj de unu sola nesto
    cxiu artikolo komencigxas per [kapvorto] komence de linio
    '''
    kwords = list()
    root = u''
    text = u''
    for line in raw:
#         print '>', line
        if line.startswith(u'['):
            wrd = line[1:line.index(u']')]
            msg('Found %s' % wrd)
            if u'|' in wrd and u'~' in wrd and root:
                kwd = wrd.replace(u'~', root).replace(u'|', u'')
            elif u'|' in wrd:
                root, fin = wrd.split(u'|', 1)
                msg('Nest root: %s' % root)
                kwd = root + fin
            elif u'~' in wrd and root:
                fin = wrd.replace(u'~', u'')
                kwd = root + fin
            else:
                root = wrd
                kwd = root
            kwords.append(kwd.replace(u'/', u'').replace(u'|', u''))
            msg('Keyword: %s' % kwd)
        text = text + u' ' + line
    if kwords:
        writeNest(kwords, text, ftxt)
            
def processFile(src, txt):
    '''Perlabori fontan dosieron
    src kaj txt estu dosieraj objektaj malfermitaj
    '''
    raw = list()
    for line in src.xreadlines():
        line = cxapeligu(line.decode('cp1251'))
        if line.startswith(u'200') or \
           line.startswith(u'201') or \
           line.startswith(u'!!!') or \
           line.startswith(u'$'):
            continue
        line = line.strip()
        if not line:            # malplena linio inter nestoj
            processNest(raw, txt)
            raw = list()
        else:
            raw.append(line)
    if raw:
        processNest(raw, txt)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        msg(__doc__)
        sys.exit(1)
    srcDir = sys.argv[1]
    targetName = sys.argv[2]
    try:
        txt = open(targetName, 'w')
    except:
        err('Ne eblas malfermi la dosieron %s!' % targetName)
    msg('Legas %s...' % srcDir)
    for fn in glob(os.path.join(srcDir, '*.txt')):
        try:
            src = open(fn)
        except:
            err('Ne eblas malfermi la dosieron %s!' % fn)
        msg('Legas %s' % fn)
        processFile(src, txt)
        src.close()
    txt.close()
    msg('Fino.')
